classdef cMRI
    %CMRI The class cMRI is the basic class in this package to save data
    %   Members: 
    %       dMRI >>> Org Data
    %       wImg >>> Width of the image
    %       hImg >>> Height of the image
    %       sImg >>> Number of slices
    %       rImg >>> Number of repetitions
    %       filePath .. The file path of the original data (null if
    %                   constructed from data.
    %   NOTE: the dimension of dMRI should coincide with the dimensions
    %   
    %   Functions:
    %       cMRI(varargin) ... Constructor
    %       readNII(obj)   ... Read NII files, usable 'filePath~=null'
    %       initialMRI(obj,para) ... Initialize the objects
    %       setPath(obj,path) ... Set the property 'filePath'
    %       getImg(obj,varargin) ... Get data with formated command
    %       showMRI()
    %           show the MRI images with customerized interface.
    %
    %   NOTE: The constructor cMRI can create an array of cMRI objects,
    %   when the first argument is an arry of cell. 
    % 
    %   See also: cASL, cDIVASL
    
    properties
        dMRI = [];
        wImg = 0; % Width of Image
        hImg = 0; % Height of Image
        sImg = []; % number of slices
        rImg = []; % number of repetitions
        
        filePath = '';
    end
    
    methods
        function obj = cMRI(varargin)
        % The obj can be constructed both from raw data and paths to the
        % files;
        % The input arguments can be both a list of files or a list of
        % data (both should be cell format)
            if nargin~=0
                inputs = varargin(1);
                num = length(inputs);
                obj(num,1) = cMRI;
                for i = 1:num
                    obj(i) = obj(i).initialMRI(inputs{i});
                end
            end
        end
    end
    
    methods
        function obj = readNII(obj)
            head_vol = spm_vol(obj.filePath);
            obj.dMRI = spm_read_vols(head_vol);
            [obj.wImg,obj.hImg,obj.sImg,obj.rImg] = size(obj.dMRI);
        end
        
        function obj = initialMRI(obj,para)
            if isempty(para)
                
            elseif ischar(para)
                if exist(para,'file')
                    obj = obj.setPath(para);
                    obj = obj.readNII();
                end
            elseif isa(para,'struct') && isfield(para,{'wImg','hImg','sImg','rImg'})
                iObj = para;
                obj = setfield(obj,'wImg',iObj.wImg,...
                    'hImg',iObj.hImg,...
                    'sImg',iObj.sImg,...
                    'rImg',iObj.rImg);
                obj.dMRI = zeros(obj.wImg,obj.hImg,obj.sImg,obj.rImg);
            elseif ndims(para) > 2 % Construct the object from data
                [obj.wImg,obj.hImg,obj.sImg,obj.rImg] = size(para);
                obj.dMRI = para;
            end
        end
        
        function obj = setPath(obj,path)
            % Set the file path of original MRI data
            obj.filePath = path;
        end
        
        function varargout = getImg(obj,varargin)
            % Get image data with formated command
            %   obj.getImg('command',paras);
            % Command should either be mri, size or path
            % when with command=MRI, additional paras should be precised,
            % or by default return the whole image data.
            % 
            if nargin <=2
                varargin = varargin{:};
                if ~iscell(varargin)
                    varargin = {varargin};
                end
            end
            if ~ischar(varargin{1})
                error('Nothing returned, becasue I dont know what you want.');
            else
                command = varargin{1};
            end
            
            
            switch lower(command)
                case 'mri'
                    nVar = length(varargin);
                    if nVar < 2
                        varargout{1} = obj.dMRI;
                    else
                        position = varargin(2:end);
                        eval(['varargout{1} = obj.dMRI(',...
                            num2str(position{1}),',',...
                            num2str(position{2}),',',...
                            num2str(position{3}),',',...
                            num2str(position{4}),...
                            ');']);
                    end
                    
                case 'size'
                    varargout{1} = [obj.wImg,obj.hImg,obj.sImg,obj.rImg];
                case 'path'
                    varargout{1} = obj.filePath;
                otherwise
                    error('Unacceptable command.');
            end
            
        end
        
   end
    
    methods
        varargout = showMRI(varargin);
    end
    
end

